package com.example.javabase.autoCompile;

import groovy.lang.GroovyClassLoader;
import org.apache.commons.jexl3.*;

import javax.annotation.Resource;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author: wyb
 * @date: 2021/11/8 16:20
 * @describe:
 * @vision 1.0
 */
public class CompileTest {

    public static void main(String[] args) throws Exception {
        compiler();
    }

    /**
     * @Author wyb
     * @Description 类是字符串
     * @Date 9:25 2021/11/9
     * @Param []
     * @return void
     **/
    public static List<Object> compiler() throws Exception {
        //groovy提供了一种将字符串文本代码直接转换成Java Class对象的功能
        GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
        //里面的文本是Java代码,但是我们可以看到这是一个字符串我们可以直接生成对应的Class<?>对象,而不需要我们写一个.java文件
        Class<?> clazz = groovyClassLoader.parseClass("package com.example.javabase.autoCompile;\n" +
                "\n" +
                "import javax.annotation.Resource;\n" +
                "\n" +
                "public class CompileClass {\n" +
                "\n" +
                "    @Resource\n" +
                "    private CompileService compileService;\n" +
                "\n" +
                "    public void business(){\n" +
                "        System.out.println(\"CompileClass.business执行...\");\n" +
                "        System.out.println(\"compileService:\"+compileService.toString());\n" +
                "        compileService.business();\n" +
                "    }\n" +
                "}\n");
        Object obj = clazz.newInstance();
        //获取属性
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println("属性："+declaredFields);
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            Resource resource = declaredField.getAnnotation(Resource.class);
            if (resource==null) {
                continue;
            }
            System.out.println("属性上的注解："+resource);
            Class<?> type = declaredField.getType();
            System.out.println("属性类型："+type.getSimpleName());
            Object bean = SpringUtil.getBean(type);
            System.out.println("属性对象："+bean);
            declaredField.set(obj,bean);
        }
        System.out.println("完整实例："+obj);

        return Arrays.asList(obj);

//        Method method = clazz.getDeclaredMethod("business");
//        method.invoke(obj);
//
//        Object val = method.getDefaultValue();
//        System.out.println(val);
    }

    public static Object exeScriptExpression(String eval, Map<String, Object> map) throws Exception {

        List<Object> compiler = compiler();

        JexlEngine engine = new JexlBuilder().create();
        JexlScript script = engine.createScript(eval);
        JexlContext context = new MapContext();
        compiler.forEach(strategy->{
            try {
                context.set(strategy.getClass().getSimpleName(),strategy);
            } catch (Exception e) {
                e.printStackTrace();
            }

        });
        Arrays.asList(Math.class).forEach(cal -> {
            context.set(cal.getSimpleName(),cal);
        });
        if (Objects.nonNull(map)) {
            map.forEach(context::set);
        }
        return  script.execute(context);
    }
}
